package com.metrology.app.biz.impl.security;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Service;
import com.metrology.common.exception.AppBusinessException;
import com.metrology.app.biz.AdminBiz;

@Service
public class MyFilterInvocationSecurityMetadataSource implements
		FilterInvocationSecurityMetadataSource {

	private final static Logger logger = LoggerFactory
			.getLogger(MyFilterInvocationSecurityMetadataSource.class);
	private AdminBiz adminBiz;
	private PathMatcher urlMatcher = new AntPathMatcher();

	public void setAdminBiz(AdminBiz adminBiz) {
		this.adminBiz = adminBiz;
	}

	public MyFilterInvocationSecurityMetadataSource() {
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		try {
			return adminBiz.loadAllConfigAttribute();
		} catch (AppBusinessException e) {
			return null;
		}
	}

	// 根据URL，找到相关的权限配置。
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		Map<String, Collection<ConfigAttribute>> resourceMap = null;
		try {
			resourceMap = this.adminBiz.loadResourceDefine();
		} catch (AppBusinessException e) {
			if (logger.isErrorEnabled()) {
				logger.error("Load resource define failure.", e);
			}
		}
		String url = ((FilterInvocation) object).getRequestUrl();
		int firstQuestionMarkIndex = url.indexOf("?");
		if (firstQuestionMarkIndex != -1) {
			url = url.substring(0, firstQuestionMarkIndex);
		}
		Iterator<String> ite = resourceMap.keySet().iterator();
		while (ite.hasNext()) {
			String resURL = ite.next();
			if (urlMatcher.match(url, resURL)) {
				return resourceMap.get(resURL);
			}
		}
		return null;
	}

	@Override
	public boolean supports(Class<?> arg0) {
		return true;
	}

}
